# MainScreen - This screen has a main menu
# Copyright (C) 2007 Lauri Taimila
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"

import os
import gtk
import clutter

from frontend.user_event import UserEvent

# Clutter widgets
from frontend.gui.widgets.selector import Selector
from frontend.gui.widgets.text_menu import TextMenu
from frontend.gui.widgets.scroll_menu import ScrollMenu
from frontend.gui.widgets.clock_label import ClockLabel
from frontend.gui.widgets.text_menu_item import TextMenuItem

from frontend.medialibrary.playable import Playable
from frontend.gui.screens.screen import Screen
from frontend.gui.transitions.transition import Transition

from utils.feed_utils import FeedEntryParser
from utils.cd_utils import eject_cd

class MainScreen(Screen):
    """
    MainScreen
    
    This screen is displayed when frontend is opened. Screen includes menu
    that allows user to navigate media center. This is main screen of the
    frontend.
    """
    
    # Size of the preview area
    PREVIEW_WIDTH = 830
    PREVIEW_HEIGHT = 580
    
    def __init__(self, ui, frontend):
        """
        Initialize home screen
        @param ui: UserInterface object
        @param frontend: FrontendClient object
        """
        self.group = clutter.Group()
        Screen.__init__(self, ui.STAGE_WIDTH, ui.STAGE_HEIGHT)
        
        self.ui = ui
        self.frontend = frontend
        self.theme = frontend.getTheme()
        
        self.preview = clutter.Group() # Group that contains preview actors
        self.preview.set_position(self.ui.x(0.07), self.ui.y(0.1))
        self.preview.show()
        self.group.add(self.preview)
        
        self.active_menu = "main"
        self.preview_menu = None # Pointer to the current preview menu
        
        self.create_main_menu()
        self.create_clock()
        
        self.ui.getStage().add(self.group)
    
    def create_clock(self):
        """Create a clock label"""
        clock = ClockLabel()
        clock.set_font_name(self.theme.getFont() + " " + str(self.ui.y(0.13)) + "px")
        clock.set_color(self.theme.getColor("screentitle"))
        clock.set_name("bgtitle")
        clock.set_position(self.ui.x(0), self.ui.y(0.87))
        clock.show()
        self.group.add(clock)
           
    def create_main_menu(self):
        """Create main menu of the home screen"""
        self.menu = ScrollMenu(10, 60)
        self.menu.set_name("mainmenu")
        self.menu.show()
        
        item0 = clutter.Label()
        item0.set_font_name(self.theme.getFont() + ' 32px')
        item0.set_name("disc")
        item0.set_text("Play CD")
        item0.set_color(self.theme.getColor("menuitem_active"))
        self.menu.add(item0)
        
        item1 = clutter.Label()
        item1.set_font_name(self.theme.getFont() + ' 32px')
        item1.set_name("tv")
        item1.set_text("Television")
        item1.set_color(self.theme.getColor("menuitem_active"))
        self.menu.add(item1)
        
        item2 = clutter.Label()
        item2.set_font_name(self.theme.getFont() + ' 32px')
        item2.set_name("videos")
        item2.set_text("Videos")
        item2.set_color(self.theme.getColor("menuitem_active"))
        self.menu.add(item2)
        
        item3 = clutter.Label()
        item3.set_font_name(self.theme.getFont() + ' 32px')
        item3.set_name("music")
        item3.set_text("Music")
        item3.set_color(self.theme.getColor("menuitem_active"))
        self.menu.add(item3)
        
        item4 = clutter.Label()
        item4.set_font_name(self.theme.getFont() + ' 32px')
        item4.set_name("photographs")
        item4.set_text("Photographs")
        item4.set_color(self.theme.getColor("menuitem_active"))
        self.menu.add(item4)
        
        item5 = clutter.Label()
        item5.set_font_name(self.theme.getFont() + ' 32px')
        item5.set_name("rss")
        item5.set_text("Headlines")
        item5.set_color(self.theme.getColor("menuitem_active"))
        self.menu.add(item5)
        
        if self.frontend.configuration.display_weather_in_frontend():
            item6 = clutter.Label() 
            item6.set_font_name(self.theme.getFont() + ' 32px')
            item6.set_name("weather")
            item6.set_text("Weather")
            item6.set_color(self.theme.getColor("menuitem_active"))
            self.menu.add(item6)
        
        if self.frontend.configuration.display_cd_eject_in_frontend():
            item7 = clutter.Label() 
            item7.set_font_name(self.theme.getFont() + ' 32px')
            item7.set_name("eject_cd")
            item7.set_text("Eject CD")
            item7.set_color(self.theme.getColor("menuitem_active"))
            self.menu.add(item7)
        
        if self.ui.get_media_player().has_media():
            self.playing_item = clutter.Label()
            self.playing_item.set_name("playing")
            self.playing_item.set_font_name(self.theme.getFont() + ' 32px')
            self.playing_item.set_text("Playing now...")
            self.playing_item.set_color(self.theme.getColor("menuitem_active"))
            self.menu.add(self.playing_item)
        
        # Separator
        item7 = clutter.Rectangle()
        item7.set_height(70)
        item7.set_color((0,0,0,0))
        self.menu.add(item7)
        
        self.menu.set_number_of_visible_items(5)
        menu_clip = self.menu.get_number_of_visible_items() * 70
        
        # Menu position
        menu_y = int((self.ui.STAGE_HEIGHT - menu_clip + 10) / 2)
        self.menu.set_position(self.ui.x(0.75), menu_y)
        
        self.group.add(self.menu)
    
    def show_playing_preview(self):
        """Create a group that displays information on current media."""
        player = self.ui.get_media_player()
        media = player.get_media()
        
        # Video preview of current media
        video_texture = player.get_texture()
        w, h = video_texture.get_size()
        x_ratio = (self.PREVIEW_WIDTH - 50) / float(w)
        y_ratio = (self.PREVIEW_HEIGHT - 50) / float(h)
        
        if x_ratio > y_ratio:
            video_texture.set_scale((self.PREVIEW_HEIGHT - 50)/float(h), 
                                   (self.PREVIEW_HEIGHT - 50)/float(h))
            new_width = int(w * ((self.PREVIEW_HEIGHT - 50)/float(h)))
            new_x = int(((self.PREVIEW_WIDTH - 50) - new_width) / 2.0)
            video_texture.set_position(int(new_x), 0)
            # Below are size and position calculations for border rectangle
            rect_x = new_x -3
            rect_y = -3
            new_width = (self.PREVIEW_HEIGHT - 50)/float(h) * w
            new_height = (self.PREVIEW_HEIGHT - 50)/float(h) * h
        else:
            video_texture.set_scale((self.PREVIEW_WIDTH - 50)/float(w), 
                                   (self.PREVIEW_WIDTH - 50)/float(w))
            new_height = int(h * ((self.PREVIEW_WIDTH - 50)/float(w)))
            new_y = int(((self.PREVIEW_HEIGHT - 50) - new_height) / 2.0)
            video_texture.set_position(0, int(new_y))
            rect_x = -3
            rect_y = new_y -3
            # Below are size and position calculations for border rectangle
            new_width = (self.PREVIEW_WIDTH - 50)/float(w) * w
            new_height = (self.PREVIEW_WIDTH - 50)/float(w) * h
        video_texture.show()
        
        # Video frame
        w, h = video_texture.get_size()
        rect = clutter.Rectangle()
        rect.set_size(int(new_width + 6), int(new_height + 6))
        rect.set_position(rect_x, rect_y)
        rect.set_color((128,128,128,192))
        rect.show()
        self.preview.add(rect)
        
        self.preview.add(video_texture)
        
        title = clutter.Label()
        title.set_color(self.theme.getColor("text"))
        title.set_font_name(self.theme.getFont() + ' 24px')
        title.set_text("Title of the current media comes here")
        title.set_position(int(rect_x + 3), int(new_height + 50))
        title.show()
        self.preview.add(title)
    
    def show_rss_preview(self):
        """Rss preview"""

        if self.frontend.get_feed_library().is_empty() is False:
            # RSS Icon
            rss = gtk.gdk.pixbuf_new_from_file(self.theme.getImage("rss_icon"))
            icon = clutter.Texture()
            icon.set_pixbuf(rss)
            icon.set_scale(0.6, 0.6)
            icon.set_position(0,30)
            icon.show()
            self.preview.add(icon)
            
            # RSS Feed Title
            title = clutter.Label()
            title.set_font_name(self.theme.getFont() + ' 48px')
            title.set_color(self.theme.getColor("title"))
            title.set_text("Recent headlines")
            title.set_position(70, 25)
            title.show()
            self.preview.add(title)
            
            menu = TextMenu(self.theme, 
                            self.frontend.get_configuration().show_effects())
            menu.set_row_count(1)
            menu.set_position(57, 100)
            menu.set_item_size(750,60)
            
            # List of latest entries. pack = (Feed object, Entry object)
            entries = self.frontend.get_feed_library().get_latest_entries(8)
            for pack in entries:
                text = pack[0].get_title() + " - " + pack[1].get_title()
                item = TextMenuItem(750, 60, self.theme, FeedEntryParser().strip_tags(text), pack[1].get_date())
                item.set_userdata([pack[0],pack[1]])
                menu.add_actor(item)
            
            menu.set_active(False)
            menu.show()
            self.preview_menu = menu
            self.preview.add(menu)
                
        else:
            # No headlines available in the library
            info = clutter.Label()
            info.set_font_name(self.theme.getFont() + ' 32')
            info.set_color(self.theme.getColor("title"))
            info.set_text("No headlines available")
            
            # Center coordinates
            x = int((self.PREVIEW_WIDTH - info.get_width()) / 2)
            y = int((self.PREVIEW_HEIGHT - info.get_height()) / 2)
            
            info.set_position(x, y)
            info.show()
            self.preview.add(info)
    
    def get_group(self):
        """Return all actors of the screen."""
        return self.group

    def get_type(self):
        """Return screen type."""
        return Screen.NORMAL
    
    def get_name(self):
        """Return screen name (human readble)"""
        return "MainScreen"
    
    def update(self):
        """
        Update screen widgets. This is called always when screen is poped from
        the screen history. Updates main menu widget.
        """
        #self.group.remove(self.menu)
        #self.create_main_menu()
    
    def update_preview_area(self, item):
        """
        Update preview area. This area displayes information of currently
        selected menuitem.
        @param item: Menuitem (clutter.Actor)
        """
        self.preview.remove_all()
        if item.get_name() == "playing":
            self.show_playing_preview()
        elif item.get_name() == "rss":
            self.show_rss_preview()
                
    def handle_user_event(self, event):   
        """ 
        Handle screen specific user events
        @param event: UserEvent object
        """
        type = event.get_type()
        
        # Scroll main menu
        if type == UserEvent.NAVIGATE_UP:
            if self.active_menu == "main":
                self.menu.scroll_down()
                self.update_preview_area(self.menu.get_selected())
            else:
                self.preview_menu.move(TextMenu.UP)
                
        elif type == UserEvent.NAVIGATE_DOWN:
            if self.active_menu == "main":
                self.menu.scroll_up()
                self.update_preview_area(self.menu.get_selected())
            else:
                self.preview_menu.move(TextMenu.DOWN)
            
        # Make preview menu active
        elif type == UserEvent.NAVIGATE_LEFT:
            if self.active_menu == "main":
                self.active_menu = "preview"
                self.menu.set_active(False)
                self.preview_menu.set_active(True)
                #FIXME: REMOVE THIS CODE AND MOVE SELECTOR TO SCROLL MENU
                self.group.find_child_by_id(self.selector_id).hide()
                
        # Make feed menu active
        elif type == UserEvent.NAVIGATE_RIGHT:
            if self.active_menu == "preview":
                self.active_menu = "main"
                self.menu.set_active(True)
                self.preview_menu.set_active(False)
                #FIXME: REMOVE THIS CODE AND MOVE SELECTOR TO SCROLL MENU
                self.group.find_child_by_id(self.selector_id).show()
            
        # Menuitem selected
        elif type == UserEvent.NAVIGATE_SELECT:
            item = self.menu.get_selected()
            
            if item.get_name() == "disc":
                self.ui.changeScreen(self.ui.createScreen("audio_cd"), Transition.FORWARD)
            elif item.get_name() == "playing":
                self.ui.changeScreen(self.ui.createScreen("video_osd"), Transition.FORWARD)
            elif item.get_name() == "music":
                self.ui.changeScreen(self.ui.createScreen("music"), Transition.FORWARD)
            elif item.get_name() == "tv":
                self.ui.changeScreen(self.ui.createScreen("tv_osd"), Transition.FORWARD)
            elif item.get_name() == "videos":
                self.ui.changeScreen(self.ui.createScreen("videos"), Transition.FORWARD)
            elif item.get_name() == "weather":
                self.ui.changeScreen(self.ui.createScreen("weather"), Transition.FORWARD)
            elif item.get_name() == "eject_cd":
                eject_cd()
            elif item.get_name() == "photographs":
                self.ui.changeScreen(self.ui.createScreen("photo_albums"), Transition.FORWARD)
            elif item.get_name() == "rss":
                if self.active_menu == "main":
                    self.ui.changeScreen(self.ui.createScreen("rss"), Transition.FORWARD)
                else:
                    data = self.preview_menu.get_current_menuitem().get_userdata()
                    self.ui.changeScreen(self.ui.createScreen("entry", data), Transition.FORWARD)    
                    
